<?php

namespace App\Http\Controllers\Income;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Income\IncomeCashController;
use App\Imports\Income\IncomeCardImport;
use App\Imports\Income\IncomePostImport;
use App\Models\Dict;
use App\Models\DictData;
use App\Models\Income\IncomeCard;
use App\Models\Income\IncomePost;
use App\Models\Bus\BusDistribution;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Facades\Excel;

class IncomeController extends Controller
{
    public $card;

    public function incomeCardList(Request $request)
    {
        $params = $countParams = $request->all();
        unset($countParams['pageNumber'], $countParams['pageSize']);
        $data = $this->getIncomeCardList($params)
            ->orderByDesc('date')
            ->orderBy('team')
            ->orderBy('line')
            ->orderBy('license_plate_num')
            ->get()
            ->toArray();
        if ($data) {
            $data = $this->transData($data);
        }
        $dataCount = $this->getIncomeCardList($countParams)->count();

        return response()->formatJson(['cardRecord' => $data, 'count' => $dataCount]);
    }

    public function getIncomeCardList($params): \Illuminate\Database\Eloquent\Builder
    {
        $query = IncomeCard::query();

        if (isset($params['license_plate_num'])) {
            $query->where('license_plate_num', 'like', '%'.$params['license_plate_num'].'%');
        }

        if (isset($params['line']) && '-1' !== $params['line']) {
            $query->where('line', $params['line']);
        }

        if ($params['date'][0] !== null && $params['date'][1] !== null) {
            $startDate = date('Y-m-d', strtotime($params['date'][0]));
            $endDate = date('Y-m-d', strtotime($params['date'][1]));
            $query->whereBetween('date', [$startDate, $endDate]);
        }

        if (isset($params['pageNumber'], $params['pageSize'])) {
            $query
                ->limit($params['pageSize'])
                ->offset(($params['pageNumber'] - 1) * $params['pageSize']);
        }

        return $query;
    }

    /**
     * 转换数据
     *
     * @param $data
     *
     * @return mixed
     */
    public function transData($data)
    {
        $card = Dict::getOptionsArrByName('卡类型');
        foreach ($data as $key => $row) {
            foreach ($row as $filed => $value) {
                if ($filed === 'card_type') {
                    $data[$key]['card_type'] = $card[$row['card_type']];
                }
            }
        }

        return $data;
    }

    /**
     * 导入一卡通收入
     *
     * @param  Request  $request
     *
     * @return mixed
     */
    public function importCard(Request $request)
    {
        $dbDate = IncomeCard::query()->get(['date'])->toArray();
        $uniqueDate = [];
        if ($dbDate) {
            $uniqueDate = array_unique(array_column($dbDate, 'date'));
        }
        $urlParse = parse_url($request->input('url'));
        $excelData = Excel::toArray(new IncomeCardImport, public_path().$urlParse['path']);
        $fullData = $excelData[0];
        //新加标志参数用来二次确认是否导入数据 值为true或者false
        $mark = $request->input('mark');

        // 结算日期
        $dateStr = substr(trim($fullData[1][0]), -17);
        $dateArr = date_parse_from_format('Y-m-d', $dateStr);
        $date = $dateArr['year'].'-'.sprintf('%02d', $dateArr['month']).'-'.sprintf('%02d', $dateArr['day']);
        if (!$mark) {
            //检查数据是否重复
            if ($uniqueDate && in_array($date, $uniqueDate, true)) {
                return response()->formatJson(false, $date . '数据已存在，是否继续导入?');
            }
        }

        // 删除前四行，前四行为标题等内容
        array_shift($fullData);
        array_shift($fullData);
        array_shift($fullData);
        array_shift($fullData);

        $xiaoji = [];
        $data = [];
        $fields = [
            'team',
            'line',
            'license_plate_num',
            'card_type',
            'charge_count',
            'free_count',
            'total_count',
            'discount_after_amt',
            'discount_before_amt',
            'discount_amt',
        ];
        $busNumberArray = BusDistribution::query()
            ->orderBy('license_plate_num')
            ->groupBy('license_plate_num')
            ->pluck('license_plate_num')
            ->toArray();
        $incomeCashController = new IncomeCashController();
        $this->card = Dict::getOptionsArrByName('卡类型');
        $unsetKeys = [];
        // 整理数据，填充合并的单元格数据
        foreach ($fullData as $k => $row) {
            if (! array_filter($row)) {
                $unsetKeys[] = $k;
                continue;
            }
            if ($row[0] === null) {
                $fullData[$k][0] = $fullData[$k - 1][0];
            }
            if ($row[1] === null) {
                $fullData[$k][1] = $fullData[$k - 1][1];
            }
            if ($row[2] === null) {
                $fullData[$k][2] = $fullData[$k - 1][2];
            }
        }
        // 删除空数据
        if ($unsetKeys) {
            foreach ($unsetKeys as $v) {
                unset($fullData[$v]);
            }
        }
        // 整理数据，填充合并的单元格数据
        foreach ($fullData as $row) {
            if ($row[0] !== '汇总' && $row[0] !== '制表人') {
                $item = [];
                foreach ($fields as $index => $field) {
                    $item[$field] = $row[$index];
                }
                $item['date'] = $date;
                if ($item['card_type'] === '小计') {
                    $xiaoji[] = $item;
                } else {
                    $item['card_type'] = array_search($item['card_type'], $this->card, true);
                    // 如果存在新的卡类型，将新的类型写入数据字典
                    if ($item['card_type'] === false) {
                        $form = [
                            'title'       => $row[3],
                            'dict_id'     => Dict::query()->where('type', 'card_type')->first()->id,
                            'value'       => count($this->card),
                            'description' => null,
                            'sort'        => count($this->card),
                        ];
                        $this->addDictData($form);
                        $this->card = Dict::getOptionsArrByName('卡类型');
                        $item['card_type'] = array_search($item['card_type'], $this->card, true);
                    }
                    if ($item['license_plate_num']) {
                        $cardNum = sprintf('%05d', str_replace('陕G', '', $item['license_plate_num']));
                        $item['license_plate_num'] = in_array($cardNum, $busNumberArray, false) ? $cardNum : $cardNum.'D';
                    }
                    if (!$mark) {
                        //检测车牌号
                        $msg =$incomeCashController->checkBusNumber($item['license_plate_num'],$busNumberArray);
                        if ($msg) {
                            return response()->formatJson('', $msg);
                        }
                    }
                    $item['created_at'] = date('Y-m-d H:i:s');
                    $data[] = $item;
                }
            }
        }
        if ($mark) {
            IncomeCard::query()->where('date', $date)->delete();
        }
        $result = IncomeCard::query()->insert($data);
        return response()->formatJson($result, '导入成功');
    }

    /**
     * 写入新的数据字典数据
     *
     * @param $form
     */
    public function addDictData($form)
    {
        $dict = new DictData($form);
        $dict->created_user_id = Auth::id();
        $dict->save();
        Cache::put('dictCache', collect(Dict::all()->toArray()), 10080);
        Cache::put('dictDataCache', collect(DictData::all()->toArray()), 10080);
        Cache::put('dictAllCache', collect(Dict::with('data')->get()->toArray()), 10080);
    }

    /**
     *  导入邮储数据
     *
     * @param  Request  $request
     *
     * @return mixed
     */
    public function importPost(Request $request)
    {
        $dbDate = IncomePost::query()->get(['date'])->toArray();
        $uniqueDate = [];
        if ($dbDate) {
            $uniqueDate = array_unique(array_column($dbDate, 'date'));
        }
        $urlParse = parse_url($request->input('url'));
        $excelData = Excel::toArray(new IncomePostImport, public_path().$urlParse['path']);
        $fullData = $excelData[0];

        // 删除第一行标题行
        array_shift($fullData);
        $date = date('Y-m-d', strtotime($fullData[0][0]));

        if ($uniqueDate && in_array($date, $uniqueDate, true)) {
            return response()->formatJson(false, $date.'数据已存在，导入终止！');
        }

        $data = [];
        $fields = [
            'date',
            'line',
            'license_plate_num',
            'self_numbering',
            'ordinary_amt',
            'ordinary_count',
            'student_amt',
            'student_count',
            'welfare_amt',
            'welfare_count',
            'total_amt',
            'total_count',
        ];
        // 整理数据，填充合并的单元格数据
        foreach ($fullData as $row) {
            if ($row[2] !== '线路汇总' && $row[2] !== '车队汇总' && $row[2] !== '每日合计') {
                $item = [];
                foreach ($fields as $index => $field) {
                    $item[$field] = $row[$index];
                }

                $item['license_plate_num'] = strlen($item['license_plate_num']) === 6 ?
                    substr($item['license_plate_num'], 1) :
                    $item['license_plate_num'];
                $item['line'] = preg_replace('/([\x80-\xff]*)/i', '', $item['line']);
                $item['created_at'] = date('Y-m-d H:i:s');
                $data[] = $item;
            }
        }

        return response()->formatJson(IncomePost::query()->insert($data), '导入成功');
    }

    public function incomePostList(Request $request)
    {
        $params = $countParams = $request->all();
        unset($countParams['pageNumber'], $countParams['pageSize']);
        $data = $this->getIncomePostList($params)
            ->orderByDesc('date')
            ->orderBy('line')
            ->orderBy('license_plate_num')
            ->get()
            ->toArray();
        $dataCount = $this->getIncomePostList($countParams)->count();

        return response()->formatJson(['postRecord' => $data, 'count' => $dataCount]);
    }

    public function getIncomePostList($params)
    {
        $query = IncomePost::query();

        if (isset($params['license_plate_num'])) {
            $query->where('license_plate_num', 'like', '%'.$params['license_plate_num'].'%');
        }

        if (isset($params['line']) && '-1' !== $params['line']) {
            $query->where('line', $params['line']);
        }

        if ($params['date'][0] !== null && $params['date'][1] !== null) {
            $startDate = date('Y-m-d', strtotime($params['date'][0]));
            $endDate = date('Y-m-d', strtotime($params['date'][1]));
            $query->whereBetween('date', [$startDate, $endDate]);
        }

        if (isset($params['pageNumber']) && isset($params['pageSize'])) {
            $query
                ->limit($params['pageSize'])
                ->offset(($params['pageNumber'] - 1) * $params['pageSize']);
        }

        return $query;
    }
}
